/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */
#include "SymbolSearchWidget.h"

#include "SymbolModel.h"

#include <QtGui/QStringListModel>
#include <QtGui/QStandardItemModel>
#include <QtGui/QTreeView>
#include <QtGui/QHeaderView>

#include <QtGui/QCompleter>

#include <QtGui/QLabel>
#include <QtGui/QComboBox>
#include <QtGui/QSpinBox>
#include <QtGui/QCheckBox>
#include <QtGui/QLineEdit>
#include <QtGui/QGridLayout>

#include <QtGui/QMessageBox>

namespace QSThink
{

	SymbolSearchWidget::SymbolSearchWidget(QWidget *parent)
		: QWidget(parent), completer(0), lineEdit(0)
	{


		QLabel *modelLabel = new QLabel;
		modelLabel->setText(tr("Model"));

		modelCombo = new QComboBox;
		modelCombo->addItem(tr("QDirModel"));
		modelCombo->addItem(tr("QDirModel that shows full path"));
		modelCombo->addItem(tr("Country list"));
		modelCombo->addItem(tr("Word list"));
		modelCombo->setCurrentIndex(0);

		QLabel *modeLabel = new QLabel;
		modeLabel->setText(tr("Completion Mode"));
		modeCombo = new QComboBox;
		modeCombo->addItem(tr("Inline"));
		modeCombo->addItem(tr("Filtered Popup"));
		modeCombo->addItem(tr("Unfiltered Popup"));
		modeCombo->setCurrentIndex(1);

		QLabel *caseLabel = new QLabel;
		caseLabel->setText(tr("Case Sensitivity"));
		caseCombo = new QComboBox;
		caseCombo->addItem(tr("Case Insensitive"));
		caseCombo->addItem(tr("Case Sensitive"));
		caseCombo->setCurrentIndex(0);

		QLabel *maxVisibleLabel = new QLabel;
		maxVisibleLabel->setText(tr("Max Visible Items"));
		maxVisibleSpinBox = new QSpinBox;
		maxVisibleSpinBox->setRange(3,25);
		maxVisibleSpinBox->setValue(10);

		wrapCheckBox = new QCheckBox;
		wrapCheckBox->setText(tr("Wrap around completions"));
		wrapCheckBox->setChecked(true);

		contentsLabel = new QLabel;
		contentsLabel->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

		connect(modelCombo, SIGNAL(activated(int)), this, SLOT(changeModel()));
		connect(modeCombo, SIGNAL(activated(int)), this, SLOT(changeMode(int)));
		connect(caseCombo, SIGNAL(activated(int)), this, SLOT(changeCase(int)));
		connect(maxVisibleSpinBox, SIGNAL(valueChanged(int)), this, SLOT(changeMaxVisible(int)));

		lineEdit = new QLineEdit;
	    
		QGridLayout *layout = new QGridLayout;
		layout->addWidget(modelLabel, 0, 0); layout->addWidget(modelCombo, 0, 1);
		layout->addWidget(modeLabel, 1, 0);  layout->addWidget(modeCombo, 1, 1);
		layout->addWidget(caseLabel, 2, 0);  layout->addWidget(caseCombo, 2, 1);
		layout->addWidget(maxVisibleLabel, 3, 0); layout->addWidget(maxVisibleSpinBox, 3, 1);
		layout->addWidget(wrapCheckBox, 4, 0);
		layout->addWidget(contentsLabel, 5, 0, 1, 2);
		layout->addWidget(lineEdit, 6, 0, 1, 2);
		this->setLayout(layout);

		changeModel();

		setWindowTitle(tr("Completer"));
		lineEdit->setFocus();
	}
	//! [3]

	

	//! [5]
	QAbstractItemModel *SymbolSearchWidget::modelFromFile(const QString& fileName)
	{
		QFile file(fileName);
		if (!file.open(QFile::ReadOnly)){
			return new QStringListModel(completer);
		}

		QStringList words;

		while (!file.atEnd()) {
			QByteArray line = file.readLine();
			if (!line.isEmpty())
				words << line.trimmed();
		}


	//! [7]
		if (!fileName.contains(QLatin1String("countries.txt")))
			return new QStringListModel(words, completer);
	//! [7]

		// The last two chars of the countries.txt file indicate the country
		// symbol. We put that in column 2 of a standard item model
	//! [8]
		QStandardItemModel *m = new QStandardItemModel(words.count(), 2, completer);
	//! [8] //! [9]
		for (int i = 0; i < words.count(); ++i) {
			QModelIndex countryIdx = m->index(i, 0);
			QModelIndex symbolIdx = m->index(i, 1);
			QString country = words[i].mid(0, words[i].length() - 2).trimmed();
			QString symbol = words[i].right(2);
			m->setData(countryIdx, country);
			m->setData(symbolIdx, symbol);
		}

		return m;
	}
	//! [9]

	//! [10]
	void SymbolSearchWidget::changeMode(int index)
	{
		QCompleter::CompletionMode mode;
		if (index == 0)
			mode = QCompleter::InlineCompletion;
		else if (index == 1)
			mode = QCompleter::PopupCompletion;
		else
			mode = QCompleter::UnfilteredPopupCompletion;

		completer->setCompletionMode(mode);
	}
	//! [10]

	void SymbolSearchWidget::changeCase(int cs)
	{
		completer->setCaseSensitivity(cs ? Qt::CaseSensitive : Qt::CaseInsensitive);
	}

	//! [11]
	void SymbolSearchWidget::changeModel()
	{
		delete completer;
		completer = new QCompleter(this);
		completer->setMaxVisibleItems(maxVisibleSpinBox->value());

		switch (modelCombo->currentIndex()) {
		default:
		case 0:
			{ // Unsorted QDirModel
				QDirModel *dirModel = new QDirModel(completer);
				completer->setModel(dirModel);
				contentsLabel->setText(tr("Enter file path"));
			}
			break;
	//! [11] //! [12]
		case 1:
			{ // DirModel that shows full paths
				DirModel *dirModel = new DirModel(completer);
				completer->setModel(dirModel);
				contentsLabel->setText(tr("Enter file path"));
			}
			break;
	//! [12] //! [13]
		case 2:
			{ // Country List
				completer->setModel(modelFromFile("data/countries.txt"));
				QTreeView *treeView = new QTreeView;
				completer->setPopup(treeView);
				treeView->setRootIsDecorated(false);
				treeView->header()->hide();
				treeView->header()->setStretchLastSection(false);
				treeView->header()->setResizeMode(0, QHeaderView::Stretch);
				treeView->header()->setResizeMode(1, QHeaderView::ResizeToContents);
				contentsLabel->setText(tr("Enter name of your country"));
			}
			break;
	//! [13] //! [14]
		case 3:
			{ // Word list
				completer->setModel(modelFromFile("data/wordlist.txt"));
				completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
				contentsLabel->setText(tr("Enter a word"));
			}
			break;
		}

		changeMode(modeCombo->currentIndex());
		changeCase(caseCombo->currentIndex());
		completer->setWrapAround(wrapCheckBox->isChecked());
		lineEdit->setCompleter(completer);
		connect(wrapCheckBox, SIGNAL(clicked(bool)), completer, SLOT(setWrapAround(bool)));
	}
	//! [14]

	//! [15]
	void SymbolSearchWidget::changeMaxVisible(int max)
	{
		completer->setMaxVisibleItems(max);
	}
	//! [15]

	//! [16]
	void SymbolSearchWidget::about()
	{
		QMessageBox::about(this, tr("About"), tr("This example demonstrates the "
			"different features of the QCompleter class."));
	}
	//! [16]
}
